package com.gzh.core.aop;

import com.gzh.core.model.vo.Result;
import com.gzh.core.util.StringUtils;
import com.gzh.core.util.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;

/**
 * @Author guanzh
 * @Date 2022/1/3 13:02
 * @Description
 */
@Aspect
@Component
@Order(10)
@Slf4j
public class ControllerResponseValidAspect {

    @Pointcut(value = "execution (public * com.gzh..*.controller..*Controller.*(..))")
    public void pointcut() {
    }

    @Around(value = "pointcut()")
    public Object process(ProceedingJoinPoint joinPoint) throws Throwable {
        //是否controller类
        boolean controller = false;
        try {
            Annotation[] annotations = joinPoint.getSignature().getDeclaringType().getAnnotations();
            if(annotations.length > 0){
                for(Annotation annotation : annotations){
                    if (annotation instanceof RestController
                            || annotation instanceof Controller) {
                        controller = true;
                        break;
                    }
                }
            }
        }catch (Exception e){
            log.error("获取类信息失败", e);
        }
        if(!controller){
            //如果不是controller，直接返回不拦截
            return joinPoint.proceed();
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String url = request.getRequestURI();
        log.info("调用: " + url + " 开始");
        Long start = System.currentTimeMillis();

        Object returnValue = null;
        try {
            returnValue = joinPoint.proceed();
        }catch (BusinessException e){
            Result result = new Result();
            result.setCode(e.getErrorCode());
            result.setMessage(e.getMessage());
            log.error("业务异常", e);
            return ResponseEntity.ok(result);
        }catch (Exception e){
            Result result = new Result();
            result.setCode("500");
            result.setMessage(StringUtils.isEmpty(e.getMessage()) ? "系统异常，请联系管理员" : e.getMessage());
            log.error("系统异常", e);
            return ResponseEntity.ok(result);
        }finally {
            log.info("调用: " + url + " 结束, 耗时[{}]ms", (System.currentTimeMillis() - start));
        }
        return returnValue;
    }
}
